const { SyncHook } = require("tapable");
const { SyncBailHook } = require("tapable");
const { SyncLoopHook } = require("tapable");
const { SyncWaterfallHook } = require("tapable");

let count = 0;
class MyCompiler {
  constructor() {
    this.hooks = {
      //创建hooks
      syncHook: new SyncHook(["name", "age"]),
      //创建bailHook
      bailHook: new SyncBailHook(["address", "date"]),
      //创建loopHook
      loopHook: new SyncLoopHook(["address", "date"]),
      //创建waterfallHook
      waterfallHook: new SyncWaterfallHook(["address", "date"]),
    };

    //用hooks监听事件（自定义plugin）
    this.hooks.syncHook.tap("event1", (name, age) => {
      console.log("event1事件监听执行了：", name, age);
    });

    /* bailHook监听 */
    //特点：如果有返回值，那么可以阻断后续事件继续执行
    this.hooks.bailHook.tap("bailHook1", (address, date) => {
      console.log("bailHook1事件监听执行了：", address, date);
      return 1;
    });

    this.hooks.bailHook.tap("bailHook2", (address, date) => {
      console.log("bailHook2事件监听执行了：", address, date);
    });

    /* loopHook监听 */
    //特点：当返回值为true，就会反复执行该事件，当返回值为undefined或者不返回内容，就退出事件
    this.hooks.loopHook.tap("loopHook1", (address, date) => {
      console.log("loopHook1事件监听执行了：", address, date);
      count++;
      if (count < 5) return true;
    });

    this.hooks.loopHook.tap("loopHook2", (address, date) => {
      console.log("loopHook2事件监听执行了：", address, date);
    });

    /* waterfallHook监听 */
    //特点：当返回值不为undefined时，会将这次返回的结果作为下次事件的第一个参数
    this.hooks.waterfallHook.tap("waterfallHook1", (address, date) => {
      console.log("waterfallHook1事件监听执行了：", address, date);
      return { name: "who are you", old: "how old are you", address, date };
    });

    this.hooks.waterfallHook.tap("waterfallHook2", params => {
      console.log("waterfallHook2事件监听执行了：", params);
    });
  }
}

const compiler = new MyCompiler();

//发出事件

// setTimeout(() => {
//   compiler.hooks.syncHook.call("why", 18);
// }, 2000);

// setTimeout(() => {
//   compiler.hooks.bailHook.call("中国杭州", "2023-09-26");
// }, 2000);

// setTimeout(() => {
//   compiler.hooks.loopHook.call("中国杭州", "2023-09-26");
// }, 2000);

setTimeout(() => {
  compiler.hooks.waterfallHook.call("中国杭州", "2023-09-26");
}, 2000);
